package controller.decoders;

import model.GameCommand;
import controller.CommandDummy;
import controller.dispatchers.AbstractDispatcher;
import controller.factories.CommandFactory;

public abstract class EventDecoder implements Runnable
{	
	// required instance variables
	protected AbstractDispatcher modelDispatcher;
	protected AbstractDispatcher viewDispatcher;
	protected AbstractDispatcher currentDispatcher;
	
	protected CommandFactory modelCommandFactory;
	protected CommandFactory viewCommandFactory;
	protected CommandFactory currentFactory;
	
	protected GameCommand gameCommand;
	
	// Override for the interface Runnable
	public void run()
	{
		synchronized( this )
		{
			try
			{
				this.wait();
				System.out.println("[CONTROLLER] " + toString() + " is awake!");
				while (!Thread.interrupted())
				{
					// Comment out until these work
//					retrieveCommand();
//					parseCommand();
//					createCommand();
					sendCommand();
					this.wait();
				}
	
			} catch (InterruptedException e)
			{
				Thread.currentThread().interrupt();
			}
		}
		System.out.println("The humanity!");
	}
	
	protected abstract void retrieveCommand();
	
	public abstract void parseCommand();
	
	private void createCommand()
	{
		this.gameCommand = this.currentFactory.createGameCommand();
	}
	
	private void sendCommand() throws InterruptedException
	{
		/**********************************
		 * TEST CODE
		 */
		// THIS IS ONLY FOR TESTING
		this.currentDispatcher = this.modelDispatcher;
		/* 
		 * THIS IS ONLY FOR TESTING
		 * THIS IS A DUMMY OBJECT!!! 
		 */
		this.gameCommand = new CommandDummy();
		/**********************************
		 * TEST CODE
		 */
		
		
		// export the command to the dispatch queue
		this.currentDispatcher.export(this.gameCommand);
		System.out.println("[CONTROLLER] " + toString() + " thread dispatched " +
			"a command to the model.");
	}
	
	public String toString()
	{
		return this.getClass().getSimpleName();
	}
}
